package ctxSemanticsGen;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

public class ParentWrapperGenerator {
	
	
	private ArrayList<ClassStructure> classStructures;
	
	
	public ParentWrapperGenerator(ArrayList<ClassStructure> classStructures){
		this.classStructures = classStructures;
	}
	
	
	
	public void generateWrapper(String path){

		// path + "/"
		run(path + Constants.FILE_SEPARATOR);
	}
		
	private void run(String path){
		
		VelocityContext context = new VelocityContext();
        
		
		// Get the layerWrapper name for the layer
    	String WrapperName = "LayerWrapper";
        context.put("wrapperName", WrapperName);
        
        
        HashMap<String,ArrayList<String[]>> params = new HashMap<String,ArrayList<String[]>>();
        HashMap<String,Boolean> retval = new HashMap<String,Boolean>();
        ArrayList<String[]> data =new ArrayList<String[]>();
        for(ClassStructure cs : classStructures){
        	
        	Set<Method> ms = cs.getAdvicedMethods();
        	for (Method advicedMethod: ms){
        		
        		String uniqueAdvicedMethodName = Utility.buildUniqueMethodName(advicedMethod);
        		String className = cs.getDescribedClass().getName();
        		String advicedMethodName = advicedMethod.getName();
        		
        		String[] s = {uniqueAdvicedMethodName,className,advicedMethodName};
        		data.add(s);
        		
        		
        		ArrayList<String[]> allMethodParameters = new ArrayList<String[]>();
        		int i = 0; 
        		for(Type t: advicedMethod.getGenericParameterTypes()){
        	        String[] parameterAndNum = {Utility.sanitizeGenericParameterType(t.toString()),
        	        				  			Utility.sanitizeGenericParameterType(Integer.toString(i))};
        	        allMethodParameters.add(parameterAndNum);
        	        i++;
        	    }
        		params.put(uniqueAdvicedMethodName,allMethodParameters);
        		
        		
        		/* Return Value */
        		boolean returnsAValue = true;
        		if (advicedMethod.getGenericReturnType().toString().equals("void")){
        			returnsAValue = false;
        		}
        		retval.put(uniqueAdvicedMethodName,returnsAValue);
        		
        		
        	}

        }
        context.put("params",params);
        context.put("data",data);
        context.put("retval",retval);
        

        /* render the template TODO: Add the encoding */
        StringWriter w = new StringWriter();
        Velocity.mergeTemplate("parentWrapperTemplate.vm", context, w );
 
        
        /* Generate the file */
        try {
        	BufferedWriter out = new BufferedWriter(new FileWriter(path + WrapperName + ".java"));
        	out.write(w.toString());
        	out.close();
        }catch (IOException e){
        	System.out.print("Error writing generated aspect to file!");
        	System.exit(1);
        }

		
	}

}


